<?php
declare (strict_types=1);

namespace app\service\logic\backend\system;

use app\constant\LogicConstant;
use app\facade\HasherFacade;
use app\model\communal\AdminTokenModel;
use app\service\logic\BaseService;
use Exception;
use thans\jwt\Token;
use think\Model;
use think\Collection;
use app\model\communal\AdminModel;
use think\db\exception\DbException;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;

final class AdminService extends BaseService
{
    protected string $modelClassName = 'AdminModel';

    /**
     * 创建
     *
     * @param $params
     * @return AdminModel|Model
     */
    public function create($params)
    {
        $params['password'] = HasherFacade::make($params['password']);
        $params['is_super'] = AdminModel::IS_SUPER_TWO;
        return AdminModel::create($params);
    }

    /**
     * 更新
     *
     * @param $params
     * @return array|mixed|Model
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function update($params)
    {
        $model = $this->getSimpleDetail($params);

        if (isset($params['password']) && !empty($params['password'])) {
            $params['password'] = HasherFacade::make($params['password']);
        } else {
            unset($params['password']);
        }

        $model->save($params);
        return $model;
    }

    /**
     * 管理员token入库
     *
     * @param $id
     * @param $token
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function insertAccessTokenByID($id, $token)
    {
        $loginsNumber = AdminTokenModel::where('admin_id', $id)->count();
        $loginLimit = config('logic.backend_login_limit');
        if ($loginsNumber >= $loginLimit) {
            // token logout
            $deleteNumber = (int)($loginsNumber - $loginLimit + 1);
            // 仅保留最新
            $deleteList = AdminTokenModel::field(['admin_id', 'token', 'created_at'])
                ->where('admin_id', $id)
                ->order(['created_at' => 'asc'])
                ->limit($deleteNumber)->select();
            $this->deleteAccessTokenByCollection($deleteList);
        }
        AdminTokenModel::create([
            'admin_id' => $id,
            'token' => $token,
        ]);
        return true;
    }

    /**
     * 批量删黑
     *
     * @param $ids
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function deleteAccessTokenByAdminIds($ids)
    {
        $deleteList = AdminTokenModel::field(['admin_id', 'token', 'created_at'])
            ->whereIn('admin_id', $ids)
            ->order(['created_at' => 'asc'])
            ->select();

        $this->deleteAccessTokenByCollection($deleteList);

        return true;
    }

    /**
     * 删黑
     *
     * @param $id
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function deleteAccessTokenByAdminId($id)
    {
        $deleteList = AdminTokenModel::field(['admin_id', 'token', 'created_at'])
            ->where('admin_id', $id)
            ->order(['created_at' => 'asc'])
            ->select();

        $this->deleteAccessTokenByCollection($deleteList);

        return true;
    }

    /**
     * 根据Collection删除并禁用管理员Token
     *
     * @param Collection $collection
     * @return bool
     */
    public function deleteAccessTokenByCollection(Collection $collection)
    {
        foreach ($collection as $key=>$model) {
            $token = $model['token'];
            auth('backend')->invalidate($token);
            $model->where('token', $token)->delete();
        }

        return true;
    }

    /**
     * @param Token $token
     * @return bool
     */
    public function deleteAccessTokenByToken(Token $token)
    {
        $token = (string)$token;
        auth('backend')->invalidate($token);
        AdminTokenModel::where('token', $token)->delete();

        return true;
    }

    /**
     * 批量删除
     *
     * @param $params
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function batchDelete($params)
    {
        $ids = explode(',', $params['ids']);

        $result = AdminModel::destroy(function ($query) use ($ids) {
            $query->whereIn('id', $ids);
        });

        if ($result) {
            $this->deleteAccessTokenByAdminIds($ids);
        }
        return $result;
    }

    /**
     * 批量设置角色
     *
     * @param $params
     * @return AdminModel
     */
    public function role($params)
    {
        $ids = explode(',', $params['ids']);
        return AdminModel::whereIn('id', $ids)->update(['role_id' => $params['role_id']]);
    }

    /**
     * 初始化平台管理员
     *
     * @return Collection
     * @throws Exception
     */
    public function initData()
    {
        $count = AdminModel::count();
        $inserts = [];
        if (0 === $count) {
            $inserts = [
                [
                    'name' => '系统管理员',
                    'account' => 'admin',
                    'password' => HasherFacade::make('^4ESMkHONoh$'),
                    // 'password' => HasherFacade::make('ooo'),
                    'is_super' => AdminModel::IS_SUPER_ONE,
                    'relation_type' => LogicConstant::CLIENT_TYPE_ONE
                ],
            ];
        }
        $adminModel = new AdminModel;
        return $adminModel->saveAll($inserts);
    }
}
